﻿using Hsp.WebNovels.Console.Utility;
using Hsp.WebNovels.Model;
using Hsp.WebNovels.Model.Models;
using HtmlAgilityPack;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using SqlSugar;
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;

namespace Hsp.WebNovels.Console
{
    class Program
    {
        static void Main(string[] args)
        {
            //var builder = WebApplication.CreateBuilder(args);
            //var config = builder.Configuration;
            //var connectionString = config.GetConnectionString("DBConnectionString");

            IConfigurationRoot _configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .Build();

            string connectionString = ConfigurationExtensions.GetConnectionString(_configuration, "DBConnectionString");

            #region SqlSugar

            //SqlSugarClient db = new(new ConnectionConfig()
            //{
            //    ConfigId = "0",
            //    DbType = DbType.SqlServer,
            //    ConnectionString = connectionString,
            //    IsAutoCloseConnection = true
            //});

            ////用来打印Sql方便你调式    
            //db.Aop.OnLogExecuting = (sql, pars) =>
            //{
            //    System.Console.WriteLine(sql + "\r\n" +
            //    db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
            //    System.Console.WriteLine();
            //};

            //{
            //    SqlSugarClient client = new(new ConnectionConfig() { ConfigId = "0", DbType = DbType.SqlServer, ConnectionString = connectionString, IsAutoCloseConnection = true });

            //    client.Open();
            //    var abc = client.Queryable<Chapter>().ToList();
            //    var def = abc;
            //}

            //return;

            #endregion

            System.Console.WriteLine("Hello Novels!");
            System.Console.WriteLine("**********************************************************");

            var encoding = "gbk";
            encoding = "utf-8";
            var webSite = "https://m.uofglam.com/";

            {
                ////var encoding = "utf-8";
                //var novelUrl = "https://www.73zw8.com/131_131787/";
                //var xpathAddress = "//div[@id=list]/dl/dd/a";

                //////通过xpath指定页面节点获取节点中对应的内容
                ////HtmlDocument? htmlAddress = HtmlDoc(novelUrl, encoding);
                ////if (htmlAddress == null)
                ////{
                ////    throw new Exception("获取小说地址代码数据为空");
                ////}
                ////var nodes = htmlAddress.DocumentNode.SelectNodes(xpathAddress);

                ////var abc = nodes;

                //var chapterUrl = "http://www.zbezhuang.com/product/4arp4/ztz04.html";
                //var nextPath = "//a[@class='url_next']";

                //HtmlDocument? htmlAddress = HtmlDoc(chapterUrl, encoding);
                //if (htmlAddress == null)
                //{
                //    throw new Exception("获取小说地址代码数据为空");
                //}
                //var nextNode = htmlAddress.DocumentNode.SelectSingleNode(nextPath);

                //var def = nextNode;

                //var nextUrl = nextNode.Attributes["href"].Value.Trim();


                //System.Console.WriteLine(nextUrl);


                //var rowcount = 7;
                //int xhcount = int.Parse((Math.Ceiling(decimal.Parse((rowcount + 2).ToString()) / 7)).ToString());
                //System.Console.WriteLine(xhcount);

                //var amount = "23ddd";
                //decimal.TryParse(amount, out decimal dAmount);
                //System.Console.WriteLine(dAmount);

            }

            {
                // HtmlAgilityPack
                // https://html-agility-pack.net/
                // https://html-agility-pack.net/online-examples
                // https://www.w3school.com.cn/xpath/xpath_syntax.asp

                // 章节目录：https://www.uofglam.com/9/9789/
                // 章节数据信息：#list/dl/dd/a

                //Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

                //HtmlWeb web = new();
                //web.OverrideEncoding = Encoding.GetEncoding("GBK");
                //var doc = web.LoadFromWebAsync(novelUrl).Result;
                //var nodes = doc.DocumentNode.SelectNodes(xpath);

                //foreach (var item in nodes)
                //{
                //    //Console.WriteLine($"标题：{item.InnerText} 地址：{item.Attributes["href"].Value}");
                //    System.Console.WriteLine($"{item.InnerText}");
                //}
            }

            {
                //var novelUrl = "https://www.uofglam.com/9/9789/";
                //var xpathAddress = "//div[@id='list']/dl/dd/a";
                //var xpathContent = "//div[@id='chaptercontent']";
                //var xpathNextPage = "//a[@id='pb_next']";

                //using HttpClient httpClient = new();
                //Uri? requestUri = new(novelUrl);
                ////以byte[]获取html
                //byte[] bytes = httpClient.GetByteArrayAsync(requestUri).Result;
                ////将byte[]重新编码成GB2312;
                //Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                //string html = Encoding.GetEncoding("GBK").GetString(bytes);
                //////解析html,并输入
                ////HtmlDocument htmlDoc = new();
                ////htmlDoc.LoadHtml(html);
                ////通过xpath指定页面节点获取节点中对应的内容
                //HtmlDocument htmlAddress = HtmlDoc(novelUrl, encoding);
                //var nodes = htmlAddress.DocumentNode.SelectNodes(xpathAddress);

                //foreach (var item in nodes)
                //{
                //    //System.Console.WriteLine($"{item.InnerText}");
                //    //System.Console.WriteLine($"{item.InnerText.Trim()}，{item.Attributes["href"].Value.Trim()}");

                //    Chapter chapter = new();
                //    chapter.Id = Guid.NewGuid().ToString().ToUpper();                    
                //    chapter.SourceTitle = item.InnerText;

                //    #region 章节数据

                //    ChapterTitle chapterTitle = TitleCleaning(item.InnerText);
                //    chapter.ChapterIdx = chapterTitle.Idx;
                //    chapter.ChapterName = chapterTitle.Name;
                //    chapter.HeadWord = chapterTitle.HeadWord;
                //    chapter.ChapterTitle = chapterTitle.Title;

                //    #endregion

                //    var chapterUrl = item.Attributes["href"].Value.Trim();
                //    HtmlDocument htmlContent = HtmlDoc(chapterUrl, encoding);
                //    var contentNode = htmlContent.DocumentNode.SelectSingleNode(xpathContent);
                //    var content = contentNode.InnerHtml;
                //    content = ContentCleaning(content);

                //    var nextUrl = GetNextUrl(htmlContent, xpathNextPage, webSite);

                //    chapter.ChapterUrl = chapterUrl;
                //    chapter.NextUrl = nextUrl;

                //    if (!string.IsNullOrEmpty(nextUrl))
                //    {
                //        var nextContent = GetNextContents(nextUrl, encoding, xpathContent, xpathNextPage, webSite);
                //        content += nextContent;
                //    }

                //    chapter.WordCount = content.Length;
                //    chapter.ValidChapter = content.Length > 500 ? 1 : 0;

                //    db.Insertable(chapter).ExecuteCommand();

                //    #region 小说内容保存

                //    Content chapterContent = new ();
                //    chapterContent.ChapterId = chapter.Id;
                //    chapterContent.NovelId = chapter.NovelId;
                //    chapterContent.Contents = content;

                //    db.Insertable(chapter).ExecuteCommand();

                //    #endregion

                //    System.Console.WriteLine(content);

                //}

                //第1章 先抄一批家再说，https://m.uofglam.com/9/9789/29592984.shtml
                //第2章 这么想死，成全你，https://m.uofglam.com/9/9789/29592985.shtml
                //第3章 捞钱的那些事，https://m.uofglam.com/9/9789/29592986.shtml
                //第4章 这朝堂的官必须继续换，https://m.uofglam.com/9/9789/29592987.shtml
                //第5章 朕的内阁首辅，https://m.uofglam.com/9/9789/29592988.shtml
                //第6章 崇祯微服私访，https://m.uofglam.com/9/9789/29592989.shtml
                //第7章 把这家店给朕砸了，https://m.uofglam.com/9/9789/29592990.shtml
                //第8章 离间和打压，https://m.uofglam.com/9/9789/29592991.shtml
                //第9章 这天下是朕的天下，https://m.uofglam.com/9/9789/29592992.shtml

            }

            {
                //// 章节内容
                //var chapterUrl = "https://m.uofglam.com/9/9789/29592984.shtml";
                //chapterUrl = "https://m.uofglam.com/9/9789/29594659.shtml";

                //var xpath = "//div[@id='chaptercontent']";

                //HtmlDocument htmlDoc = HtmlDoc(chapterUrl, encoding);
                //var contentNode = htmlDoc.DocumentNode.SelectSingleNode(xpath);
                //var content = contentNode.InnerHtml;
                //content = ContentCleaning(content);
                ////content.Trim('\n');
                ////content = content.Replace("\r\n", "\n");

                //var nextPath = "//a[@id='pb_next']";
                //var nextUrl = GetNextUrl(htmlDoc, nextPath, webSite);

                ////var nextNode = htmlDoc.DocumentNode.SelectSingleNode(nextPath);
                ////var nextUrl = nextNode.Attributes["href"].Value.Trim();

                ////System.Console.WriteLine(nextUrl);
                ////// /9/9789/29592984_2.shtml
                ////// javascript:sam()
                ////if (!nextUrl.Contains("javascript"))
                ////{
                ////    if (!nextUrl.Contains("http"))
                ////    {
                ////        nextUrl = webSite + nextUrl;

                ////        HtmlDocument nextHtmlDoc = HtmlDoc(nextUrl, encoding);
                ////        var nextContentNode = nextHtmlDoc.DocumentNode.SelectSingleNode(xpath);
                ////        var nextContent = nextContentNode.InnerText;
                ////        content += ContentCleaning(nextContent);
                ////    }
                ////}

                //if (!string.IsNullOrEmpty(nextUrl))
                //{
                //    var nextContent = GetNextContents(nextUrl, encoding, xpath, nextPath, webSite);
                //    content += nextContent;
                //}

                //System.Console.WriteLine(content);
            }

            System.Console.WriteLine("**********************************************************");
            System.Console.WriteLine("Bye Novels!");
            System.Console.ReadKey();
        }


        private static HtmlDocument HtmlDoc(string url, string encoding)
        {
            using HttpClient client = new();
            Uri? requestUri = new(url);
            //以byte[]获取html
            byte[] bytes = client.GetByteArrayAsync(requestUri).Result;
            //将byte[]重新编码成GB2312;
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            string html = Encoding.GetEncoding(encoding).GetString(bytes);
            //解析html,并输入
            HtmlDocument htmlDoc = new();
            htmlDoc.LoadHtml(html);

            return htmlDoc;
        }

        private static ChapterTitle TitleCleaning(string title)
        {
            ChapterTitle chapterTitle = new ();

            var chapterTemplate = "第$2章";

            var chapterIdx = 0;
            var titleContent = title;
            string expTitle = "([第]{0,1})([○零一二三四五六七八九十百千\\d]{1,})([节章]{0,1}[：:。, ]{0,2})([\\s\\S]*?)";
            var titleChapter = TextHelper.ContentExtract(title, expTitle); // 标题章节数字

            if (!string.IsNullOrEmpty(titleChapter))
            {
                titleChapter = titleChapter.Replace(Environment.NewLine, "&");
                titleChapter = titleChapter.Split('&')[0];

                titleContent = title.Replace(titleChapter, ""); // 标题名称（除去章节数字）
                titleChapter = titleChapter.Replace("。", "").Replace("：", "");

                var expChineseDig = "([○零一二三四五六七八九十百千]{1,})";
                var strChineseChapter = TextHelper.ContentExtract(titleChapter, expChineseDig); // 章节中文数字 
                strChineseChapter = strChineseChapter.Replace(Environment.NewLine, "&");
                strChineseChapter = strChineseChapter.Split('&')[0];

                if (strChineseChapter.Length == 0)
                {
                    // 阿拉伯数字
                    titleChapter = TextHelper.ContentExtract(titleChapter, "([\\d]{1,})");
                    titleChapter = titleChapter.Replace(Environment.NewLine, "");
                    int.TryParse(titleChapter, out chapterIdx);
                }
                else
                {
                    if (TextHelper.ContentExtract(strChineseChapter, "([十百千]{1,})").Length > 0)
                    {
                        chapterIdx = int.Parse(TextHelper.DecodeMoneyCn(strChineseChapter).ToString());
                    }
                    else
                    {
                        chapterIdx = int.Parse(TextHelper.DecodeSimpleCn(strChineseChapter));
                    }
                }

                if (!string.IsNullOrEmpty(titleContent))
                {
                    titleContent = titleContent.Trim().TrimEnd('.');
                    titleContent = titleContent.TrimStart(','); // 标题前面的半角逗号清理

                    #region 处理标题中“几更”信息

                    if (!string.IsNullOrEmpty(titleContent) && titleContent.IndexOf("更", StringComparison.Ordinal) > -1)
                    {
                        var exp = "(（{1})([\\s\\S]*?)(）{1})";
                        var result = TextHelper.ContentExtract(titleContent, exp);

                        if (!string.IsNullOrEmpty(result) && result.IndexOf("更", StringComparison.Ordinal) > -1)
                        {
                            result = result.TrimEnd('\n').TrimEnd('\r');
                            result = result.Replace("\n", "").Replace("\r", "");
                            titleContent = titleContent.Replace(result, "");
                        }

                    }

                    #endregion

                    titleContent = titleContent.Replace("（新书求支持）", "");
                    titleContent = titleContent.Replace("（求收藏、求鲜花）", "");
                    titleContent = titleContent.Replace("（求收藏）", "");
                    titleContent = titleContent.Replace("（求订阅）", "");
                    titleContent = titleContent.Replace("（改）", "");

                    //titleContent = titleContent.Replace("（第一更！）", "");
                    //titleContent = titleContent.Replace("（第二更！）", "");
                    //titleContent = titleContent.Replace("（第三更！）", "");
                    //titleContent = titleContent.Replace("（第四更！）", "");
                    //titleContent = titleContent.Replace("（第五更！）", "");
                    //titleContent = titleContent.Replace("（第六更！）", "");
                    //titleContent = titleContent.Replace("（第七更！）", "");
                    //titleContent = titleContent.Replace("（第八更！）", "");
                    //titleContent = titleContent.Replace("（第九更！）", "");

                    //titleContent = titleContent.Replace("（第十更！）", "");
                    //titleContent = titleContent.Replace("（第十一更！）", "");
                    //titleContent = titleContent.Replace("（第十二更！）", "");
                    //titleContent = titleContent.Replace("（第十三更！）", "");
                    //titleContent = titleContent.Replace("（第十四更！）", "");
                    //titleContent = titleContent.Replace("（第十五更！）", "");

                    //titleContent = titleContent.Replace("（第一更）", "");
                    //titleContent = titleContent.Replace("（第二更）", "");
                    //titleContent = titleContent.Replace("（第三更）", "");

                    titleContent = titleContent.Replace("【求鲜花】", "");
                    titleContent = titleContent.Replace("【求首订】", "");
                    titleContent = titleContent.Replace("【鲜花】", "");

                    titleContent = titleContent.Replace("求订阅", "");
                    titleContent = titleContent.Replace("求全定", "");
                    titleContent = titleContent.Replace("求收藏", "");
                    titleContent = titleContent.Replace("求首订", "");

                    titleContent = titleContent.Replace("重复已修改", "");
                    titleContent = titleContent.Replace("补上昨天的", "");

                    titleContent = titleContent.Replace("【】", "").Replace("（）", "").Replace("()", "");

                    //（改）
                }

                // 第$2章
                if (chapterIdx > 0)
                {
                    titleChapter = chapterTemplate.Replace("$2", chapterIdx.ToString());
                }

                if (string.IsNullOrEmpty(titleChapter))
                {
                    titleChapter = "第$2章".Replace("$2", chapterIdx.ToString());
                }

            }


            chapterTitle.Idx = chapterIdx;
            chapterTitle.Name = titleChapter;
            chapterTitle.HeadWord = titleContent;
            chapterTitle.Title = titleChapter + " " + titleContent;

            return chapterTitle;
        }

        private static string ContentCleaning(string content)
        {
            //content = content.Trim();
            content = content.TrimStart('\r').TrimStart('\n');
            content = content.TrimEnd('\n').TrimStart('\r');

            content = content.Replace("<br><br>", "<br>").Replace("<br>", Environment.NewLine);

            content = content.Replace("&nbsp;", "");
            content = content.Replace("&#12290;", "。");
            content = content.Replace("&#24819;", "想");

            content = content.Replace("\r\n”", "”");
            content = content.Replace("\r\n、", "、");

            content = ContentHelper.RegexReplace("<p[^>]*>([\\s\\S]*?)</p>", content, "");


            content = content.Replace("(第1/4页)本章未完，请点击&#8595;&#8595;&#8595;继续阅读", "");
            content = content.Replace("(第2/4页)本章未完，请点击&#8595;&#8595;&#8595;继续阅读", "");
            content = content.Replace("(第3/4页)本章未完，请点击&#8595;&#8595;&#8595;继续阅读", "");
            content = content.Replace("(第4/4页)本章未完，请点击&#8595;&#8595;&#8595;继续阅读", "");

            return content;
        }

        /// <summary>
        /// 获取下一页地址
        /// </summary>
        /// <param name="htmlDoc"></param>
        /// <param name="nextPath"></param>
        /// <param name="webSite"></param>
        /// <returns></returns>
        private static string GetNextUrl(HtmlDocument htmlDoc, string nextPath, string webSite)
        {
            var nextNode = htmlDoc.DocumentNode.SelectSingleNode(nextPath);
            var nextUrl = nextNode.Attributes["href"].Value.Trim();
            if (nextUrl.Contains("javascript") || string.IsNullOrEmpty(nextUrl)) return "";
            if (nextUrl.Contains("http")) return nextUrl;
            return $"{webSite}{nextUrl}";
        }

        // 递归获取下一页内容
        private static string GetNextContents(string nextUrl, string encoding, string xpath, string nextPath, string webSite)
        {
            HtmlDocument nextHtmlDoc = HtmlDoc(nextUrl, encoding);
            var nextContentNode = nextHtmlDoc.DocumentNode.SelectSingleNode(xpath);
            if (nextContentNode == null) return "";
            var nextContent = nextContentNode.InnerHtml;
            var content = ContentCleaning(nextContent);

            nextUrl = GetNextUrl(nextHtmlDoc, nextPath, webSite);

            if (!string.IsNullOrEmpty(nextUrl))
            {
                content += GetNextContents(nextUrl, encoding, xpath, nextPath, webSite);
            }

            return content;
        }

        //自动获取网页编码
        private static Encoding GetWebEncoding(string serverUrl)
        {
            WebRequest request = WebRequest.Create(serverUrl);
            WebResponse response = request.GetResponse();
            Stream sr = response.GetResponseStream();
            byte[] buffer = new byte[1200];
            sr.Read(buffer, 0, buffer.Length);
            string head = Encoding.Default.GetString(buffer);
            string regPatt = @"charset\s*=\s*(?<encode>\w+)";
            Regex regEncode = new Regex(regPatt, RegexOptions.IgnoreCase
                | RegexOptions.Compiled);
            string encodname = regEncode.Match(head).Result("${encode}");

            return Encoding.GetEncoding(encodname);
        }

    }
}
